package com.joinway.framework.admin.core.utils;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.LinkedList;
import java.util.List;

import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang.StringUtils;

import com.joinway.framework.admin.bean.domain.RoleTreeMenu;
import com.joinway.framework.admin.bean.domain.TreeMenu;
import com.joinway.framework.admin.core.bean.view.Menu;
import com.joinway.framework.admin.core.bean.view.MenuAttribute;
import com.joinway.framework.extension.utils.DataUtils;

public final class UIHelper {

	@SuppressWarnings("rawtypes")
	final static Comparator TREE_MENU_COMPARATOR = new Comparator(){
		@Override
		public int compare(Object o1, Object o2) {
			TreeMenu tm1 = (TreeMenu)o1;
			TreeMenu tm2 = (TreeMenu)o2;
			
			return tm1.getOrder() - tm2.getOrder();
		}
	};
	
	@SuppressWarnings("unchecked")
	public static List<Menu> convert(List<? extends TreeMenu> menus, String pageSuffix) throws Exception {
		List<TreeMenu> roots = new LinkedList<>();
		for(TreeMenu m : menus){
			if(m.getParentId() == 0){
				roots.add(m);
			}
		}
//				Arrays.asList((TreeMenu[])menus.stream().filter(m -> m.getParentId() == 0).toArray());//Filter.create(menus, Condition.create("parentId", 0)).result();
		List<Menu> rootMenus = null;
		
		if(CollectionUtils.isNotEmpty(roots)){
			Collections.sort(roots, TREE_MENU_COMPARATOR);
			
			rootMenus = new ArrayList<>();
			
			for(TreeMenu tm : roots){
				Menu menu = create(tm, pageSuffix);
				rootMenus.add(menu);
			}
			
			for(Menu parent : rootMenus){
				setChildrenMenus(parent, menus, pageSuffix);
			}
			
			// 重置含有子菜单的父菜单选中状态，如果所有子菜单被选中，父菜单才会设置成选中状态，否则设置为非选中状态
			resetMenuCheckedFlag(rootMenus);
		}
		
		return rootMenus;
	}
	
	@SuppressWarnings("unchecked")
	static void setChildrenMenus(Menu parent, List<? extends TreeMenu> menus, String pageSuffix) throws Exception {
		List<TreeMenu> childrenMenus = new LinkedList<>();
		for(TreeMenu m : menus){
			if(m.getParentId() == parent.getId()){
				childrenMenus.add(m);
			}
		}
		
		if(CollectionUtils.isNotEmpty(childrenMenus)){
			Collections.sort(childrenMenus, TREE_MENU_COMPARATOR);
			
			List<Menu> children = new ArrayList<>();
			
			for(TreeMenu tm : childrenMenus){
				Menu menu = create(tm, pageSuffix);
				children.add(menu);
			}
			
			parent.setChildren(children);
			
			for(Menu p : children){
				setChildrenMenus(p, menus, pageSuffix);
			}
		}
	}
	
	static Menu create(TreeMenu tm, String pageSuffix){
		Menu menu = new Menu();
		menu.setId(tm.getId());
		menu.setText(tm.getText());
		menu.setIconCls(tm.getIcon());
		
		MenuAttribute attribute = new MenuAttribute();
		String url = tm.getUrl();
		if(!StringUtils.startsWith(url, "http")){
			url += pageSuffix;
		}
		attribute.setUrl(url);
		
		menu.setAttribute(attribute);
		
		if(tm instanceof RoleTreeMenu){
			RoleTreeMenu rtm = (RoleTreeMenu)tm;
			menu.setChecked(DataUtils.convertBool(rtm.getOwned()));
		}
		
		return menu;
	}
	
	static void resetMenuCheckedFlag(List<Menu> menus){
		for(Menu menu : menus){
			menu.setChecked(isAllChildrenChecked(menu));
			
			if(CollectionUtils.isNotEmpty(menu.getChildren())){
				resetMenuCheckedFlag(menu.getChildren());
			}
		}
	}
	
	static boolean isAllChildrenChecked(Menu menu){
		boolean allChecked = menu.isChecked();
		
		if(CollectionUtils.isNotEmpty(menu.getChildren())){
			List<Menu> children = menu.getChildren();
			allChecked = true;
			for(Menu m : children){
				if(!isAllChildrenChecked(m)){
					allChecked = false;
					break;
				}
			}
		}
		
		return allChecked;
	}
	
	private UIHelper(){}
	
	static class TreeMenuOrderComparator<T extends TreeMenu> implements Comparator<T>{
		@Override
		public int compare(T t1, T t2) {
			return t1.getOrder() - t2.getOrder();
		}
	}
}
